package com.hjb.service.utils;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author <a href="mailto:panxinwen@yingu.com">Pan Xinwen</a>
 * @version 1.0 2017年2月15日 下午3:53:31
 */
public abstract class StringUtil {
	/** 随机数对象 */
	private static final Random random = new Random();
	/** 数字与字母字典 */
	private static final char[] LETTER_AND_DIGIT = ("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
	/** 数字与字母字典长度 */
	private static final int LETTER_AND_DIGIT_LENGTH = LETTER_AND_DIGIT.length;
//	private static final MessageFactory messageFactory = ParameterizedMessageFactory.INSTANCE;



	/**
	 * 检测字符串是否为空字符串
	 * 字符串为空的标准：null或全部由空字符组成的字符串
	 * @param str 待检测字符串
	 * @return
	 * <li>true：字符串是空字符串</li>
	 * <li>false：字符串不是空字符串</li>
	 */
	public static boolean isEmpty(String str) {
		return (str == null || str.trim().length() == 0);
	}


	/**
	 * 检测字符串是否为空字符串
	 * 字符串为空的标准：null或全部由空字符组成的字符串
	 * @param str 待检测字符串
	 * @return
	 * <li>true：字符串是空字符串</li>
	 * <li>false：字符串不是空字符串</li>
	 */
	public static boolean isEmpty(Object obj) {

		return (obj == null || obj.toString().trim().length() == 0);

	}

	/**
	 * 检测字符串是否不为空字符串
	 * 字符串为空的标准：null或全部由空字符组成的字符串
	 * @param str 待检测字符串
	 * @return
	 * <li>true：字符串不是空字符串</li>
	 * <li>false：字符串是空字符串</li>
	 * @see #isEmpty(String)
	 */
	public static boolean isNotEmpty(String str) {
		return !isEmpty(str);
	}

	/**
	 * 将对象转换为字符串
	 * @param input 待转换对象
	 * @param defVal 对象转换为空字符串时的默认返回值
	 * @return 转换后的字符串
	 * @see #getString(String)
	 * @see #getString(String, String)
	 */
	public static String getString(Object input, String defVal) {
		return (input == null) ? defVal : getString(input.toString(), defVal);
	}

	/**
	 * 转换字符串
	 * @param input 待转换字符串
	 * @param defVal 默认转换值
	 * @return 转换后的字符串
	 * <li>字符串为null或全部由空白字符组成的字符串时，返回defVal参数指定的值</li>
	 * <li>其他情况，返回去掉字符串两端空白字符后的字符串</li>
	 */
	public static String getString(String input, String defVal) {
		return (isEmpty(input)) ? defVal : input.trim();
	}

	/**
	 * 生成固定长度的随机字符串
	 * @param len 随机字符串长度
	 * @return 生成的随机字符串
	 */
	public static String getRandomString(final int len) {
		if (len < 1) return "";
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			sb.append(LETTER_AND_DIGIT[random.nextInt(LETTER_AND_DIGIT_LENGTH)]);
		}
		return sb.toString();
	}

	/**
	 * 生成固定长度的随机字符串
	 * @param len 随机字符串长度
	 * @param dictionary 字符串字典
	 * @return 生成的随机字符串
	 */
	public static String getRandomString(final int len, char[] dictionary) {
		if (len < 1) return "";
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			sb.append(dictionary[random.nextInt(dictionary.length)]);
		}
		return sb.toString();
	}

	/** 
	* @Title      :getRandomNum 
	* @param      :@param len
	* @param      :@return 
	* @return     :String 
	* @Description:获取数字随机数
	*/
	public static String getRandomNum(int len) {
		char[] dictionary = {'1','2','3','4','5','6','7','8','9','0'};
		return getRandomString(len,dictionary);
	}
	/**
	 * 创建一个新的字符串
	 * @param bytes 字符串内容字节数组
	 * @param charset 字符串字节编码
	 * @return 新创建的字符串
	 */
	public static String newString(byte[] bytes, String charset) {
		try {
			return new String(bytes, charset);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("不支持的字符集：" + charset, e);
		}
	}

	/**
	 * 取得字符串字节数组
	 * @param str 字符串
	 * @param charset 字符串字节编码
	 * @return 字符串内容字节数组
	 */
	public static byte[] getBytes(String str, String charset) {
		if (str == null) return null;
		try {
			return str.getBytes(charset);
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("不支持的字符集：" + charset, e);
		}
	}

	/**
	 * 从右侧开始截取固定长度的字符串
	 * @param str 待截取字符串
	 * @param length 截取的长度
	 * @return
	 * <li>null：字符串为空或字符串长度小于截取的长度</li>
	 * <li>非null：截取字符串后的结果</li>
	 */
	public static String right(String str, int length) {
		return (str == null || str.length() < length) ? null : str.substring(str.length() - length);
	}
	/**
	 * 从左侧开始截取固定长度的字符串
	 * @param str 待截取字符串
	 * @param length 截取的长度
	 * @return
	 * <li>null：字符串为空或字符串长度小于截取的长度</li>
	 * <li>非null：截取字符串后的结果</li>
	 */
	public static String left(String str, int length) {
		return (str == null || str.length() < length) ? null : str.substring(0, length);
	}

	/**
	 * 截取定长字符串（中文、字符、字母、数字……）
	 * @param str
	 * @param fixedWidth
	 * @return
	 */
	public static String subFixedWidthString(String str, int fixedWidth) {
		if(str.length() <= fixedWidth) {
			return str;
		}else{
			StringBuilder ret = new StringBuilder();
		    fixedWidth = fixedWidth << 1;
		    int currentWidth = 0;
		    for (int i = 0; i < str.length(); i++) {
		        char ch = str.charAt(i);
		        currentWidth += (ch < 128) ? 1 : 2;
		        if (currentWidth > fixedWidth) break;
		        ret.append(ch);
		    }
		    ret.append("…");
		    return ret.toString();
		}
	}

	/**
	 * 比较两个字符串大小
	 * @param str1 字符串1
	 * @param str2 字符串2
	 * @return
	 * <li>-1：str1小</li>
	 * <li>0：两字符串相等</li>
	 * <li>1：str2小</li>
	 */
	public static int compare(String str1, String str2) {
		if (str1 == null && str2 == null) return 0;
		if (str1 == null) return -1;
		if (str2 == null) return 1;

		int len1 = str1.length();
		int len2 = str2.length();
		int len = Math.min(len1, len2);
		for (int i = 0; i < len; i++) {
			char ch1 = str1.charAt(i);
			char ch2 = str2.charAt(i);
			if (ch1 == ch2) continue;
			return (ch1 < ch2) ? -1 : 1;
		}

		if (len1 == len2) return 0;
		return (len1 < len2) ? -1 : 1;
	}

	/**
	 * 根据参数填充占位符,构建字符串消息,例如:
	 * msg=我是{} params:小明 返回值为:我是小明
	 * @param msg
	 * @param params
	 * @return
	 */
//	public static String buildMessage(String msg, Object... params) {
//		return messageFactory.newMessage(msg,params).getFormattedMessage();
//	}
	public static String buildMessage(String msg, Object... params) {
		return "";
	}

	/**
	 * 过滤空格
	 * @param str 待过滤字符串
	 * @return 过滤结果
	 */
	public static String trim (String str) {
		return str == null ? null : str.trim();
	}

	/**
	 * 将字符串指定索引位的字符转换为大写
	 * @param source
	 * @param index
	 *
	 * @return
	 */
	public static String toUpperCase(String source, int index) {
		char[] chars = source.toCharArray();
		chars[index] = Character.toUpperCase(chars[index]);
		return new String(chars);
	}


	// GENERAL_PUNCTUATION 判断中文的“号
	// CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号
	// HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的，号
	public static final boolean isChinese(char c) {
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
			return true;
		}
		return false;
	}


	public static final boolean isChinese(String strName) {
		char[] ch = strName.toCharArray();
		for (int i = 0; i < ch.length; i++) {
			char c = ch[i];
			if (isChinese(c)) {
				return true;
			}
		}
		return false;
	}

	public static final boolean isMobile(String str) {
		Pattern pattern = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$"); // 验证手机号
		Matcher matcher = pattern.matcher(str);
		boolean b = matcher.matches();
		return b;
	}

	public static final boolean isEmail(String str) {
		String paString ="^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
		Pattern pattern = Pattern.compile(paString); // 验证邮箱
		Matcher matcher = pattern.matcher(str);
		boolean b = matcher.matches();
		return b;
	}

	public static String toStringRule(String[] strs){

		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "1");
		map.put("3", "2");
		map.put("6", "3");
		map.put("9", "4");
		map.put("12", "5");
		map.put("24", "6");
		map.put("36", "7");

		Map<String,String> map1 = new HashMap<String,String>();
		map1.put("1", "1");
		map1.put("2", "3");
		map1.put("3", "6");
		map1.put("4", "9");
		map1.put("5", "12");
		map1.put("6", "24");
		map1.put("7", "36");

		List<String> list = new ArrayList<String>();

		for(String key:strs){

			list.add(map.get(key));

		}
		String rval = "";
		for(int i=0;i<list.size();i++){

			if(i==0) {

				rval=map1.get(list.get(0));

			}else{

				int m = Integer.parseInt(list.get(i));
				int n = Integer.parseInt(list.get(i-1));

				if(m-n==1){

					rval=rval+"-"+map1.get(list.get(i));;

				}else{

					rval=rval+","+map1.get(list.get(i));

				}

			}

		}

//		System.out.println(rval);

		String[] cval = rval.split(",");
		String bval="";
		for(String str1:cval){

			if(str1.contains("-")) {

				if(str1.split("-").length>2){

					String llo = str1.replace(str1.substring(2,str1.lastIndexOf("-")),"")+",";

					if(llo.split("-").length>2){

						llo = llo.replace("--", "-");

					}

					bval+=llo;

				}else{

					bval+=str1+",";
				}

			}else{
				bval+=str1+",";

			}

		}

		return bval.substring(0,bval.length()-1);

	}

    public static int stringNumbers(String str)
    {
    	int counter = 0;
        if (str.indexOf("-")==-1)
        {
            return 0;
        }
        else if(str.indexOf("-") != -1)
        {
            counter++;
            stringNumbers(str.substring(str.indexOf("-")+4));
            return counter+counter+1;
        }
        return 0;
    }


	public static String[] getStrings(String[] strs,String type){

		Map<String,String> map = new HashMap<String,String>();
		map.put("ydl1", "2001011");
		map.put("ydl3", "2001031");
		map.put("ydl6", "2001061");
		map.put("ydl12", "2001121");
		map.put("ydl24", "2001241");

		map.put("yyl12", "3001121");
		map.put("yyl24", "3002241");

		map.put("gbl9", "1001011");

		String[] rt = new String [strs.length];
		for(int i=0;i<rt.length;i++) {

			rt[i]=map.get(type+strs[i]);

		}

		return rt;

	}
	
    //生成随机数字和字母,  
    public static String getStringRandom(int length) {  
          
        String val = "";  
        Random random = new Random();  
          
        //参数length，表示生成几位随机数  
        for(int i = 0; i < length; i++) {  
              
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";  
            //输出字母还是数字  
            if( "char".equalsIgnoreCase(charOrNum) ) {  
                //输出是大写字母还是小写字母  
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;  
                val += (char)(random.nextInt(26) + temp);  
            } else if( "num".equalsIgnoreCase(charOrNum) ) {  
                val += String.valueOf(random.nextInt(10));  
            }  
        }  
        return val;  
    }  

    public static String getCharNo(int length){
		String [] chars = {"A","B","C","D","E","F","G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z"};
		String [] nums = {"0","1","2","3","4","5","6","7","8","9"};
		String str = "";  
	    Random random = new Random();  
	    for (int i = 0; i < length; i++) {  
	        boolean b = random.nextBoolean();  
	        if (b) { // 字母
	        	int index = random.nextInt(24);
	            str += chars[index];
	        } else { // 数字  不取0和1等容易和字母混淆的数字
	        	int index = 1;
	        	while(index<=1) index=random.nextInt(10);
	            str += nums[index];  
	        }  
	    } 
	    return str;
	}
    
    public static String get22Str(){
    	
    	SimpleDateFormat simple = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    	return simple.format(new Date())+getFixLenthString(5);
    }
    
    /* 
     * 返回长度为【strLength】的随机数，在前面补0 
     */  
    private static String getFixLenthString(int strLength) {  
          
        Random rm = new Random();  
          
        // 获得随机数  
        double pross = (1 + rm.nextDouble()) * Math.pow(10, strLength);  
      
        // 将获得的获得随机数转化为字符串  
        String fixLenthString = String.valueOf(pross);  
      
        // 返回固定的长度的随机数  
        return fixLenthString.substring(1, strLength + 1);  
    }
    
    public static Date formatStrToDate(String str){
    	
    	try {
			return new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").parse(str);
		} catch (ParseException e) {
		
			e.printStackTrace();
		}
    	
    	return new Date();
    	
    }
    
    public static String getIpAddr() { 
    	HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String ip = request.getHeader("x-forwarded-for"); 
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
            ip = request.getHeader("Proxy-Client-IP"); 
        } 
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
            ip = request.getHeader("WL-Proxy-Client-IP"); 
        } 
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
            ip = request.getRemoteAddr(); 
        } 
        return ip; 
    } 
}
